package com.miya.order.configure.rabbitmq.dead;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 死信演示配置:
 *      这里申明两个交换机exchange, 一个是业务 BUSINESS_EXCHANGE, 一个是死信 DEAD_LETTER_EXCHANGE
 *      业务 BUSINESS_EXCHANGE 下绑定两个业务队列 BUSINESS_QUEUEA + BUSINESS_QUEUEB
 *      业务队列都配置了同一个死信 DEAD_LETTER_EXCHANGE, 并分别配饰了路由
 *      在死信 DEAD_LETTER_EXCHANGE下绑定了两个死信队列, 设置的路由key 分别为业务队列里配置的路由key
 *
 * @author Caixiaowei
 * @date 2022/02/18
 */
@Configuration
public class DeadLetterDemoConfigure {

	/**
	 * 业务交换机
	 */
	public static final String BUSINESS_EXCHANGE = "dead.letter.demo.simple.business.exchange";

	/**
	 * 业务队列A
	 */
	public static final String BUSINESS_QUEUEA = "dead.letter.demo.simple.business.queuea";

	/**
	 * 业务队列B
	 */
	public static final String BUSINESS_QUEUEB = "dead.letter.demo.simple.business.queueb";

	/**
	 * 死信交换机
	 */
	public static final String DEAD_LETTER_EXCHANGE = "dead.letter.demo.simple.deadletter.exchange";

	/**
	 * 死信队列A路由key
	 */
	public static final String DEAD_LETTER_QUEUEA_ROUTING_KEY = "dead.letter.demo.simple.deadletter.queuea.routingkey";

	/**
	 * 死信队列B路由key
	 */
	public static final String DEAD_LETTER_QUEUEB_ROUTING_KEY = "dead.letter.demo.simple.deadletter.queueb.routingkey";

	/**
	 * 死信队列A
	 */
	public static final String DEAD_LETTER_QUEUEA = "dead.letter.demo.simple.deadletter.queuea";

	/**
	 * 死信队列B
	 */
	public static final String DEAD_LETTER_QUEUEB = "dead.letter.demo.simple.deadletter.queueb";

	/**
	 * 声明业务Exchange
	 *
	 * @return {@link FanoutExchange}
	 */
	@Bean("businessExchange")
	public FanoutExchange businessExchange(){
		return new FanoutExchange(BUSINESS_EXCHANGE);
	}

	/**
	 * 声明死信Exchange
	 *
	 * @return {@link DirectExchange}
	 */
	@Bean("deadLetterExchange")
	public DirectExchange deadLetterExchange(){
		return new DirectExchange(DEAD_LETTER_EXCHANGE);
	}

	/**
	 * 声明业务队列A
	 *
	 * @return {@link Queue}
	 */
	@Bean("businessQueueA")
	public Queue businessQueueA(){
		Map<String, Object> args = new HashMap<>(2);
        //x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
		args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        //x-dead-letter-routing-key  这里声明当前队列的死信路由key
		args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUEA_ROUTING_KEY);
		return QueueBuilder.durable(BUSINESS_QUEUEA).withArguments(args).build();
	}

	/**
	 * 声明业务队列B
	 *
	 * @return {@link Queue}
	 */
	@Bean("businessQueueB")
	public Queue businessQueueB(){
		Map<String, Object> args = new HashMap<>(2);
        //x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
		args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        //x-dead-letter-routing-key  这里声明当前队列的死信路由key
		args.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUEB_ROUTING_KEY);
		return QueueBuilder.durable(BUSINESS_QUEUEB).withArguments(args).build();
	}

	/**
	 * 声明死信队列A
	 *
	 * @return {@link Queue}
	 */
	@Bean("deadLetterQueueA")
	public Queue deadLetterQueueA(){
		return new Queue(DEAD_LETTER_QUEUEA);
	}

	/**
	 * 声明死信队列B
	 *
	 * @return {@link Queue}
	 */
	@Bean("deadLetterQueueB")
	public Queue deadLetterQueueB(){
		return new Queue(DEAD_LETTER_QUEUEB);
	}

	/**
	 * 声明业务队列A绑定关系
	 *
	 * @param queue    队列
	 * @param exchange 交换
	 * @return {@link Binding}
	 */
	@Bean
	public Binding businessBindingA(@Qualifier("businessQueueA") Queue queue,
	                                @Qualifier("businessExchange") FanoutExchange exchange){
		return BindingBuilder.bind(queue).to(exchange);
	}

	/**
	 * 声明业务队列B绑定关系
	 *
	 * @param queue    队列
	 * @param exchange 交换
	 * @return {@link Binding}
	 */
	@Bean
	public Binding businessBindingB(@Qualifier("businessQueueB") Queue queue,
	                                @Qualifier("businessExchange") FanoutExchange exchange){
		return BindingBuilder.bind(queue).to(exchange);
	}

	/**
	 * 声明死信队列A绑定关系
	 *
	 * @param queue    队列
	 * @param exchange 交换
	 * @return {@link Binding}
	 */
	@Bean
	public Binding deadLetterBindingA(@Qualifier("deadLetterQueueA") Queue queue,
	                                  @Qualifier("deadLetterExchange") DirectExchange exchange){
		return BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_QUEUEA_ROUTING_KEY);
	}

	/**
	 * 声明死信队列B绑定关系
	 *
	 * @param queue    队列
	 * @param exchange 交换
	 * @return {@link Binding}
	 */
	@Bean
	public Binding deadLetterBindingB(@Qualifier("deadLetterQueueB") Queue queue,
	                                  @Qualifier("deadLetterExchange") DirectExchange exchange){
		return BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_QUEUEB_ROUTING_KEY);
	}
}
